package ui.component
{

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.MouseEvent;

	import util.ColorUtil;

	public class Button extends Sprite implements IUIComponent
	{
		protected var skin:Bitmap;
		////////////////////
		protected var defaultSkin:BitmapData;
		protected var overSkin:BitmapData;
		protected var downSkin:BitmapData;
		protected var disableSkin:BitmapData;
		///////////////
		protected var state:uint;
		private var _handler:Function;
		private var _enable:Boolean = true;

		public var onDownHandler:Function;

		public static const DEFAULT_STATE:uint = 1;
		public static const OVER_STATE:uint = 2;
		public static const DOWN_STATE:uint = 3;
		public static const DISABLE_STATE:uint = 4;

		public var id:uint;

		public function Button(defaultData:BitmapData, overData:BitmapData = null, downData:BitmapData = null, disableData:BitmapData = null, handler:Function = null)
		{
			super();

			skin = new Bitmap();
			this.addChildAt(skin, 0);
			updateSkin(defaultData, overData, downData, disableData);
			updateState(DEFAULT_STATE);
			addListeners();
			_handler = handler;
			buttonMode = true;
		}

		public function updateSkin(defaultData:BitmapData, overData:BitmapData = null, downData:BitmapData = null, disableData:BitmapData = null):void
		{
			defaultSkin = defaultData;
			overSkin = overData;
			downSkin = downData;
			disableSkin = disableData;
		}

		private function addListeners():void
		{
			addEventListener(MouseEvent.CLICK, clickHandler);
			addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
			addEventListener(MouseEvent.MOUSE_UP, upHandler);
			addEventListener(MouseEvent.MOUSE_OVER, overHandler);
			addEventListener(MouseEvent.MOUSE_OUT, outHandler);
		}

		protected function clickHandler(event:MouseEvent):void
		{
			if(_enable)
			{
				if(_handler != null)
				{
					_handler(this);
				}
			}
		}

		protected function downHandler(event:MouseEvent):void
		{
			if(_enable && downSkin != null)
			{
				updateState(DOWN_STATE);
			}

			if(_enable && onDownHandler != null)
			{
				onDownHandler(this);
			}
		}

		protected function upHandler(event:MouseEvent):void
		{
			if(_enable && downSkin != null)
			{
				overHandler(null);
			}
		}

		protected function overHandler(event:MouseEvent):void
		{
			if(_enable && overSkin != null)
			{
				updateState(OVER_STATE);
			}
		}

		protected function outHandler(event:MouseEvent):void
		{
			if(_enable && overSkin != null)
			{
				updateState(DEFAULT_STATE);
			}
		}

		public function updateState(data:uint):void
		{
			switch(data)
			{
				case DEFAULT_STATE:
					skin.bitmapData = defaultSkin;
					break;
				case OVER_STATE:
					skin.bitmapData = overSkin;
					break;
				case DOWN_STATE:
					skin.bitmapData = downSkin;
					break;
				case DISABLE_STATE:
					skin.bitmapData = disableSkin;
					break;
			}
			state = data;
		}

		public function setIcon(bmd:BitmapData):void
		{
			skin.bitmapData = bmd;
		}

		public function set enable(value:Boolean):void
		{
			_enable = value;
			buttonMode = value;

			if(_enable)
			{
				updateState(DEFAULT_STATE);
			}
			else if(disableSkin)
			{
				updateState(DISABLE_STATE);
			}

			if(value)
			{
				ColorUtil.setDefaultColor(this);
			}
			else
			{
				ColorUtil.setBlackColor(this);
			}
		}

		public function get enable():Boolean
		{
			return _enable;
		}

		public function dispose():void
		{
			skin.bitmapData = null;
			removeEventListener(MouseEvent.CLICK, clickHandler);
			removeEventListener(MouseEvent.MOUSE_DOWN, downHandler);
			removeEventListener(MouseEvent.MOUSE_OVER, overHandler);
			removeEventListener(MouseEvent.MOUSE_OUT, outHandler);
		}

		public function get clickCallback():Function
		{
			return _handler;
		}

		public function set clickCallback(value:Function):void
		{
			_handler = value;
		}
	}
}